/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include <arch/exception.h>
#include <arch/exception_decode.h>
#include <arch/esr.h>

const char *esr_ec_decode_sts[] = {
    [0] = "EC[31:26] == 000000, Exception with an unknown reason",
    [1] = "EC[31:26] == 000001, Exception from a WFI or WFE instruction",
    [3] = "EC[31:26] == 000011, Exception from an MCR or MRC access",
    [4] = "EC[31:26] == 000100, Exception from an MCRR or MRRC access",
    [5] = "EC[31:26] == 000101, Exception from an MCR or MRC access",
    [6] = "EC[31:26] == 000110, Exception from an LDC or STC access to CP14",
    [7] =
        "EC[31:26] == 000111, Exception from an access to an Advanced SIMD or floating-point register, resulting from CPACR_EL1.FPEN or CPTR_ELx.TFP",
    [8]  = "EC[31:26] == 001000, Exception from an MCR or MRC access",
    [12] = "EC[31:26] == 001100, Exception from an MCRR or MRRC access",
    [14] = "EC[31:26] == 001110, Exception from an Illegal execution state, or a PC or SP alignment fault",
    [10] = "EC[31:26] == 010001, Exception from HVC or SVC instruction execution",
    [18] = "EC[31:26] == 010010, Exception from HVC or SVC instruction execution",
    [19] = "EC[31:26] == 010011, Exception from SMC instruction execution in AArch32 state",
    [21] = "EC[31:26] == 010101, Exception from HVC or SVC instruction execution",
    [22] = "EC[31:26] == 010110, Exception from HVC or SVC instruction execution",
    [23] = "EC[31:26] == 010111, Exception from SMC instruction execution in AArch64 state",
    [24] = "EC[31:26] == 011000, Exception from MSR, MRS, or System instruction execution in AArch64 state",
    [31] = "EC[31:26] == 011111, IMPLEMENTATION DEFINED exception to EL3",
    [32] = "EC[31:26] == 100000, Exception from an Instruction abort",
    [33] = "EC[31:26] == 100001, Exception from an Instruction abort",
    [34] = "EC[31:26] == 100010, Exception from an Illegal execution state, or a PC or SP alignment fault",
    [36] = "EC[31:26] == 100100, Exception from a Data abort, from lower exception level",
    [37] = "EC[31:26] == 100101, Exception from a Data abort, from current exception level",
    [38] = "EC[31:26] == 100110, Exception from an Illegal execution state, or a PC or SP alignment fault",
    [40] = "EC[31:26] == 101000, Exception from a trapped Floating-point exception",
    [44] = "EC[31:26] == 101100, Exception from a trapped Floating-point exception",
    [47] = "EC[31:26] == 101111, SError interrupt",
    [48] = "EC[31:26] == 110000, Exception from a Breakpoint or Vector Catch debug event",
    [49] = "EC[31:26] == 110001, Exception from a Breakpoint or Vector Catch debug event",
    [50] = "EC[31:26] == 110010, Exception from a Software Step debug event",
    [51] = "EC[31:26] == 110011, Exception from a Software Step debug event",
    [52] = "EC[31:26] == 110100, Exception from a Watchpoint debug event",
    [53] = "EC[31:26] == 110101, Exception from a Watchpoint debug event",
    [56] = "EC[31:26] == 111000, Exception from execution of a Software Breakpoint instructio",
};

void perror_ec(uint64_t ec)
{
    dprintf("%s \n", esr_ec_decode_sts[ec]);
}
void dump_decode_esr(uint64_t esr_value)
{
    uint64_t esr_ec;
    uint64_t esr_il;
    uint64_t esr_iss;
    esr_decode_bit(esr_value, &esr_ec, &esr_il, &esr_iss);

    perror_ec(esr_ec);
}
